<?php

namespace App\Service\VendorClient\Shopyongyou;

use App\Service\Code\Normal;
use App\Service\BaseService;
use Service\AppService\IdService;
use App\Service\TaskServer\TaskWorker;
use App\Model\PssModel\ServiceConfig;
use Hyperf\Utils\Coroutine;
use Hyperf\Utils\WaitGroup;

/**
 * 用友供应商SDK
 * @author hujian
 */
class ShopyongyouApiClient extends BaseService {

    //供应商编号
    const SUPPLIER_CODE = 'shopyongyou';
    //access_token缓存前缀
    const SHOP_YONGYOU_ACCESS_TOKEN_PREFIX = 'shop_yongyou_access_token';
    //access_token缓存时间 1小时
    const ACCESS_TOKEN_EXPIRE = 3600;

    public $warehouse = [];
    //只需要这几个仓库
    // public static $warehouse = [
    //     '1717356306590335020' => '10',  //拼多多专用仓    深圳市艾禧汇贸易有限公司1
    //     '1717356306590334980' => '01',  //龙华仓       深圳市艾禧汇贸易有限公司1
    //     '1720932639948931088' => '12',  //龙华（艾哲拉） 深圳市艾哲拉贸易有限公司1
    //     '1720932648538865678' => '30',  //拼多多专用仓   深圳市艾哲拉贸易有限公司1
    //     '1720932648538865674' => '31',  //龙华仓（巨臣）  深圳市巨臣物美商贸有限公司1
    //     '1720932648538865801' => '56',  //拼多多专用仓     深圳市巨臣物美商贸有限公司1
    //     '1720932648538865804' => '59',  //丽梵龙华仓     深圳市丽梵贸易有限公司1
    //     '1720932648538865838' => '64',  //拼多多专用仓    深圳市丽梵贸易有限公司1
    // ];

    /**
     * 查询结存价的一些配置映射
     */
    public static $queryBalanceMap = [
        //拼多多专用仓    深圳市艾禧汇贸易有限公司1
        '1717356306590335020' => [
            'accentity'  => '1717304079783821324',//会计主体ID
            "accpurpose" => "1712514727410663694",//核算目的ID
            "accbook"    => "1723022906041565202",//账簿ID
            "warehouse"  => "1717356306590335020",//仓库ID
            "stockOrg"   => "1717304079783821324",//库存组织ID
        ],
        //龙华仓       深圳市艾禧汇贸易有限公司1
        '1717356306590334980' => [
            'accentity'  => '1717304079783821324',//会计主体ID
            "accpurpose" => "1712514727410663694",//核算目的ID
            "accbook"    => "1723022906041565202",//账簿ID
            "warehouse"  => "1717356306590334980",//仓库ID
            "stockOrg"   => "1717304079783821324",//库存组织ID
        ],
        //龙华（艾哲拉） 深圳市艾哲拉贸易有限公司1
        '1720932639948931088' => [
            'accentity'  => '1717304088373755918',//会计主体ID
            "accpurpose" => "1712514727410663694",//核算目的ID
            "accbook"    => "1728108654148714516",//账簿ID
            "warehouse"  => "1720932639948931088",//仓库ID
            "stockOrg"   => "1717304088373755918",//库存组织ID
        ],
        //拼多多专用仓   深圳市艾哲拉贸易有限公司1
        '1720932648538865678' => [
            'accentity'  => '1717304088373755918',//会计主体ID
            "accpurpose" => "1712514727410663694",//核算目的ID
            "accbook"    => "1728108654148714516",//账簿ID
            "warehouse"  => "1720932648538865678",//仓库ID
            "stockOrg"   => "1717304088373755918",//库存组织ID
        ],
        //龙华仓（巨臣）  深圳市巨臣物美商贸有限公司1
        '1720932648538865674' => [
            'accentity'  => '1717304088373755935',//会计主体ID
            "accpurpose" => "1712514727410663694",//核算目的ID
            "accbook"    => "1728856425134817303",//账簿ID
            "warehouse"  => "1720932648538865674",//仓库ID
            "stockOrg"   => "1717304088373755935",//库存组织ID
        ],
        //拼多多专用仓     深圳市巨臣物美商贸有限公司1
        '1720932648538865801' => [
            'accentity'  => '1717304088373755935',//会计主体ID
            "accpurpose" => "1712514727410663694",//核算目的ID
            "accbook"    => "1728856425134817303",//账簿ID
            "warehouse"  => "1720932648538865801",//仓库ID
            "stockOrg"   => "1717304088373755935",//库存组织ID
        ],
        //丽梵龙华仓     深圳市丽梵贸易有限公司1
        '1720932648538865804' => [
            'accentity'  => '1717304096963690507',//会计主体ID
            "accpurpose" => "1712514727410663694",//核算目的ID
            "accbook"    => "1728857017840304147",//账簿ID
            "warehouse"  => "1720932648538865804",//仓库ID
            "stockOrg"   => "1717304096963690507",//库存组织ID
        ],
        //拼多多专用仓    深圳市丽梵贸易有限公司1
        '1720932648538865838' => [
            'accentity'  => '1717304096963690507',//会计主体ID
            "accpurpose" => "1712514727410663694",//核算目的ID
            "accbook"    => "1728857017840304147",//账簿ID
            "warehouse"  => "1720932648538865838",//仓库ID
            "stockOrg"   => "1717304096963690507",//库存组织ID
        ],
    ];

    //api路由
    public static $apiMap = [
        // "appKey": "ddc41496f130454cb2838e10d0a35651",
        // "appSecret": "a12109f5d3b17f2790d8a9cd59342abe6e25113a",
        // "accessTokenUrl": "https:\/\/yonbip-core3.diwork.com\/iuap-api-auth\/open-auth\/selfAppAuth\/getAccessToken",
        // "baseUrl": "https:\/\/yonbip-core3.diwork.com\/iuap-api-gateway",
        // "orgCode": "101",
        // "limit": "10",
        "createOrder"         => "/yonbip/sd/dst/tradevouch/import",
        "cancelOrder"         => "/yonbip/sd/dst/returnorder/import",
        "queryExpress"        => "/yonbip/sd/dst/tradevouch/query",
        "queryGoods"          => "/yonbip/digitalModel/product/list",
        "queryGoodsPrice"     => "/yonbip/digitalModel/product/detail",
        "queryStockNum"       => "/yonbip/scm/stockanalysis/list",
        "queryWarehouse"      => "/yonbip/digitalModel/warehouse/detail",
        "queryTradeOrder"     => "/yonbip/sd/dst/tradeorder/query",
        "generateRefundOrder" => "/yonbip/sd/dst/refundorder/generatebytrade",
        "afterSaleOrder"      => "/yonbip/sd/dst/returnorder/add",
        "queryBalance"        => "/yonbip/EFI/fieia/queryBalance",//存货成本查询
    ];

    //配置文件
    private $config = [];

    public function __construct($apiBody = []) {
        $this->config = $apiBody;
        // $this->warehouse = isset($this->config['warehouse']) && !empty($this->config['warehouse']) ? json_decode($this->config['warehouse'], true) : [];
    }

    /**
     * 创建订单
     * 请求域名 https://yonbip-core3.diwork.com/iuap-api-gateway
     * 请求地址 /yonbip/sd/dst/tradevouch/import
     * @param array $params
     * @return array
     */
    public function createOrder($param = []) {
        if (empty($param['supplierOrder']) || empty($param['orderGoods']) || empty($param['order']) || empty($param['binfo'])) {
            return Normal::returnCode(Normal::FAIL, "except param supplierOrder or orderGoods or order or binfo");
        }
        if (!isset($param['binfo']['event_code']) || empty($param['binfo']['event_code'])) {
            return Normal::returnCode(Normal::FAIL, "渠道商未配置用友店铺编码，请联系相关人员");
        }
        $orderInfo = $param['supplierOrder'];
        $goodsList = $param['orderGoods'];
        $order     = $param['order'];
        $binfo     = $param['binfo'];
        $shopcode  = $binfo['event_code'];
        $order_sn  = $orderInfo['supplier_dsn'];
        //支付流水号
        $pay_sn = $order['paySerial'] ?? $orderInfo['pay_sn'];
        //订单时间
        $order_time = $orderInfo['cd'] ? date('Y-m-d H:i:s', $orderInfo['cd']) : date('Y-m-d H:i:s', time());
        //支付时间
        $pay_time = isset($order['payTime']) && !empty($order['payTime']) ? date('Y-m-d H:i:s', $order['payTime']) : date('Y-m-d H:i:s', time());
        //运费分摊
        $deliver_money = $orderInfo['deliver_money'];
        //下单支付的时候支付信息
        $apply_extends = @json_decode($orderInfo['apply_extends'], true);

        //判断支付方式是否存在
        $payCommanyCode = $apply_extends['payCommanyCode'] ?? '';
        $payCommanyCode = $order['payCommanyCode'] ?? $payCommanyCode;

        //获取下单商品信息
        $palceOrderGoods    = [];
        $totalGoodsMoney    = '0.00';
        $goodsTotalMoney    = '0.00';
        $goodsTotalMoneyNot = '0.00';
        $wayTaxFee          = '0.00';
        foreach ($goodsList as $key => $item) {
            $tax_rate         = bcadd('1', (string)$item['tax_rate'], 4);
            $price            = $item['price'];
            $spec_num         = $item['spec_num'];
            $quantity         = $item['quantity'];
            $supplier_skucode = $item['supplier_skucode'];
            $goods_type       = $item['goods_type'];
            $batch_no         = $item['batch_no'];
            // $stockRes         = $this->queryStockNum([$supplier_skucode], $batch_no);
            // if ($stockRes['code'] != Normal::SUC) {
            //     return $stockRes;
            // }
            // if (!isset($stockRes['data']['data']['recordList']) || empty($stockRes['data']['data']['recordList'])) {
            //     return Normal::returnCode(Normal::FAIL, '现存量报表查询数据为空');
            // }
            // $stock = reset($stockRes['data']['data']['recordList']);
            // if (!isset($this->warehouse[$stock['warehouse']])) {
            //     return Normal::returnCode(Normal::FAIL, '现存量报表查询数据的仓库对应编码不存在');
            // }
            //实际购买数量(下单数量 X 起售数量)
            $buyAcount = $spec_num * $quantity;
            if ($key == 0) {
                $singleDeliveryMoney = bcdiv((string)$deliver_money, (string)$quantity, 3);
                $singleDeliveryMoney = bcmul((string)$singleDeliveryMoney, (string)100, 1);
                $singleDeliveryMoney = bcdiv((string)ceil($singleDeliveryMoney), (string)100, 2);
                $price               = bcadd((string)$price, (string)$singleDeliveryMoney, 2);
            }
            //不含税价格
            $singleGoodsPrice = bcdiv((string)$price, (string)$tax_rate, 3);
            $singleGoodsPrice = bcmul((string)$singleGoodsPrice, (string)100, 1);
            $singleGoodsPrice = bcdiv((string)ceil($singleGoodsPrice), (string)100, 2);
            //商品不含税总价
            $goodsTotalPrice = bcmul((string)$singleGoodsPrice, (string)$quantity, 2);
            //含税总价
            $goodsTotalPriceTax = bcmul((string)$price, (string)$quantity, 2);
            //税费
            $tax    = bcsub((string)$price, (string)$singleGoodsPrice, 2);
            $taxAll = bcmul((string)$tax, (string)$quantity, 2);

            //判断是不是保税订单
            $taxAll = $goods_type == 1 ? $taxAll : 0;
            //不含税总金额
            $goodsTotalMoneyNot = bcadd((string)$goodsTotalMoneyNot, (string)$goodsTotalPrice, 2);
            //含税总金额
            $goodsTotalMoney = bcadd((string)$goodsTotalMoney, (string)$goodsTotalPriceTax, 2);
            //总税费
            $wayTaxFee = bcadd((string)$wayTaxFee, (string)$taxAll, 2);
            //下单商品组
            $goodsInfo         = [
                // 'num_iid'   => $item['supplier_skucode'],//线上商品编码(线上商品编码和商品SKU编码不可同时为空)    示例：2053500000112484
                'oid'           => $order_sn,
                'total_fee'     => $goodsTotalPrice,//商品金额，精确到2位小数，单位元。如200.07，表示200元7分    示例：199
                'tid'           => $order_sn,//交易编号    示例：JY202004103000937001713464004
                'itemcode'      => $item['supplier_skucode'],//商品SKU编码(线上商品编码和商品SKU编码不可同时为空)     示例：1559411932844288
                'shopcode'      => $shopcode,//店铺编码    示例：002
                'price'         => $price,//商品价格    示例：199
                'num'           => (string)$quantity,//购买数量（整数 >0）    示例：1,
                // 'warehouseCode' => $this->warehouse[$stock['warehouse']],//仓库编码(需要oms匹配仓库的可以不传)先通过批次号和店铺编码 查询到仓库id 再通过查询仓库接口 查询到仓库编码
                'warehouseCode' => $this->config['warehouseCode'],//仓库编码(需要oms匹配仓库的可以不传)
                // 'shipWarehouseCode' => ,//自有发货仓库编码
            ];
            $palceOrderGoods[] = $goodsInfo;
        }
        $couponFee    = $goodsTotalMoney > $orderInfo['real_total_money'] ? bcsub($goodsTotalMoney, $orderInfo['real_total_money'], 2) : '0.00';
        $requestParam = [
            'receiver_phone'    => $orderInfo['recveive_phone'],//收货电话
            'receiver_town'     => $orderInfo['receive_address'],//收货人所在乡镇/街道 示例：北清路58号
            'tid'               => $order_sn,//交易编号    示例：JY202004103000937001713464004
            'buyer_nick'        => $orderInfo['buyer_realname'],//买家昵称    示例：200227937
            'pay_time'          => $pay_time,//付款的时间
            'buyer_message'     => "渠道名称【{$binfo['name']}】",//买家留言
            'seller_memo'       => "渠道名称【{$binfo['name']}】",//卖家备注 示例：卖家备注
            'type'              => '在线支付',//交易类型（”在线支付”，”货到付款”,”门店支付”）    示例：在线支付
            'status'            => '待发货',//线上交易状态：待付款、待发货、已发货、交易完成、交易关闭、部分发货、暂停    示例：交易关闭
            'created'           => $order_time,//下单时间，格式"2019-06-28 11:04:22"    示例：2020-04-10 11:11:33
            'receiver_city'     => $orderInfo['city'],//收货人所在城市    示例：金华市
            'shopcode'          => $shopcode,//店铺编码    示例：test
            'receiver_state'    => $orderInfo['province'],//省    示例：浙江省
            'receiver_address'  => $orderInfo['receive_address'],//详细地址    示例：人民法院
            'receiver_district' => $orderInfo['district'],//收货人所在地区    示例：义乌市
            'receiver_mobile'   => $orderInfo['recveive_phone'],//收货手机号    示例：17774250881
            'receiver_name'     => $orderInfo['receive_name'],//收货人姓名    示例：龚XX
            'OrderInfo'         => $palceOrderGoods,//表体信息
        ];
        $data         = [
            'method' => 'createOrder',
            'data'   => [
                'externalData' => [$requestParam],
                'partParam'    => [
                    'orgCode' => $this->config['orgCode']//组织编码    示例：123
                ]
            ],
        ];
        return $this->execute($data);
    }

    /**
     * 获取取消订单
     * 请求域名    https://yonbip-core3.diwork.com/iuap-api-gateway
     * 请求地址    /yonbip/sd/dst/returnorder/import
     */
    public function cancelOrder($params = []) {
        //先查询订单  然后拿到数据 再调用  参照订单生退换货单 用这个参数直接填充 退换货订单导入 接口
        if (!isset($params['binfo']['event_code']) || empty($params['binfo']['event_code'])) {
            return Normal::returnCode(Normal::FAIL, "渠道商未配置用友店铺编码，请联系相关人员");
        }
        $orderSn       = $params['supplierOrder']['supplier_dsn'];
        $shopcode      = $params['binfo']['event_code'];
        $tradeOrderRes = $this->queryTradeOrder($orderSn, $shopcode);
        if ($tradeOrderRes['code'] != Normal::SUC) {
            return Normal::returnCode(Normal::FAIL, '订单查询失败');
        }
        if (!isset($tradeOrderRes['data']['data']['info']) || empty($tradeOrderRes['data']['data']['info'])) {
            return Normal::returnCode(Normal::FAIL, "订单查询数据为空");
        }
        $tradeOrder = reset($tradeOrderRes['data']['data']['info']);

        if (!isset($tradeOrder['tradeOrderDetail']) || empty($tradeOrder['tradeOrderDetail'])) {
            return Normal::returnCode(Normal::FAIL, "订单查询数据订单子表（订单表体行）数据为空");
        }
        $bodyIds       = array_column($tradeOrder['tradeOrderDetail'], 'id');
        $genRefundData = [
            'ids'     => $tradeOrder['id'],
            'pubts'   => $tradeOrder['pubts'],
            'bodyIds' => array_column($tradeOrder['tradeOrderDetail'], 'id'),
        ];
        $genRefundRes  = $this->generateRefundOrder($genRefundData);
        if ($genRefundRes['code'] != Normal::SUC) {
            return Normal::returnCode(Normal::FAIL, '参照订单生退换货单查询失败');
        }
        // 参照订单生退换货单
        $genRefund = $genRefundRes['data']['data'] ?? [];
        if (!$genRefund) {
            return Normal::returnCode(Normal::FAIL, '参照订单生退换货单查询数据为空');
        }
        $goodStatus = 'BUYER_RECEIVED';
        if (isset($params['supplierOrder']['order_status'])) {
            $goodStatus = $params['supplierOrder']['order_status'] == 1 ? 'BUYER_NOT_RECEIVED' : 'BUYER_RECEIVED';
        }
        $added = [];
        $head  = [];
        foreach ($genRefund as $v) {
            foreach ($v['refundOrderDetail'] as $vv) {
                $added[] = $vv;
                // $added[] = [
                //     'enableNum'            => $vv['enableNum'],//可退数量
                //     'total_fee'            => $vv['total_fee'],
                //     'num'                  => $vv['num'],
                //     'payment'              => $vv['payment'],
                //     'oid'                  => $vv['oid'],//子订单号
                //     'actualReturnQuantity' => $vv['actualReturnQuantity'],//实际收货数量    示例：1
                //     'citemID'              => $vv['citemID'],//商品skuID    示例：1162770732994816
                //     'price'                => $vv['price'],//价格，精确到2位小数，单位元。如200.07，表示200元7分
                //     'created'              => $vv['created'],//退款申请时间
                //     'productID'            => $vv['productID'],//商品ID    示例：1162770706141440
                //     'refund_phase'         => $vv['refund_phase'],//退款阶段
                //     'sku_id'               => $vv['sku_id'],//sku_id    示例：1162770732994816
                //     'title'                => $vv['title'] ?? $vv['product_name'],//商品标题    示例：办公用签字笔1012
                //     'good_status'          => $goodStatus,//货物状态
                //     'tid'                  => $vv['tid'],//交易编号    示例：404818115517251453
                //     'cTradeLineId'         => $vv['cTradeLineId'],//电商订单行ID    示例：1174095207993601
                //     'product_name'         => $vv['product_name'],//商品名称名称    示例：inv017保质期
                //     'num_iid'              => $vv['num_iid'] ?? $vv['product_code'],//平台商品编码    示例：526421307171
                //     'iWarehouseId'         => $vv['iWarehouseId'],//仓库id    示例：1158535624593664
                //     'sku'                  => $vv['sku'] ?? $vv['product_skuname'],//平台商品SKU信息    示例：颜色分类:蓝色
                //     'cTradeCodeLine'       => $vv['cTradeCodeLine'],//电商订单号    示例：DSDD11062019041000000001
                //     'isGift'               => $vv['isGift'],//是否赠品    示例：0
                // ];
            }
            unset($v['refundOrderDetail']);
            $head[] = $v;
            // $head[] = [
            //     'buyer_nick'   => $v['buyer_nick'],//买家昵称
            //     'srctype'      => $v['srctype'],//单据来源 2-导入
            //     'tid'          => $v['tid'],
            //     'plat'         => $v['plat'],
            //     'total_fee'    => $v['payment'],
            //     'refundNum'    => $v['refundNum'],
            //     'created'      => $v['created'],
            //     'order_status' => $v['order_status'],
            //     'refund_fee'   => $v['refund_fee'],
            //     'shopCode'     => $shopcode,
            //     'refund_type'  => $v['refund_type'],//退款类型 1-退款
            //     'reason'       => $params['order']['exceptReason'] ?? '下游申请订单退款作废',
            //     'good_status'  => $goodStatus,//货物状态
            //     'refund_phase' => $v['refund_phase'],//退款阶段 aftersale-售后
            // ];
        }

        $data = [
            'method' => 'afterSaleOrder',
            'data'   => [
                'externalData' => [
                    //退换货单的表体信息
                    'Added' => $added,
                    //退换货单的表头信息
                    'Head'  => $head,
                ]
            ],
        ];
        return $this->execute($data);

        // $goodStatus = 'BUYER_RECEIVED';
        // if (isset($params['supplierOrder']['order_status'])) {
        //     $goodStatus = $params['supplierOrder']['order_status'] == 1 ? 'BUYER_NOT_RECEIVED' : 'BUYER_RECEIVED';
        // }
        // $requestParam = [];
        // foreach ($genRefund as $v) {
        //     $refundOrderDetail = [];
        //     foreach ($v['refundOrderDetail'] as $vv) {
        //         $refundOrderDetail[] = [
        //             'cwhcode'              => $vv['iWarehouseId'],//仓库id    示例：1158535624593664
        //             'good_status'          => $goodStatus,//货物状态
        //             'refund_phase'         => $vv['refund_phase'],//退款阶段
        //             'tid'                  => $vv['tid'],//交易编号    示例：404818115517251453
        //             'oid'                  => $vv['oid'],//子订单号    示例：404818115517251453
        //             'product_name'         => $vv['product_name'],//商品名称名称    示例：inv017保质期
        //             'title'                => $vv['title'] ?? $vv['product_name'],//商品标题    示例：办公用签字笔1012
        //             'sku'                  => $vv['sku'] ?? $vv['product_skuname'],//平台商品SKU信息    示例：颜色分类:蓝色
        //             'num'                  => $vv['num'],//退/换货数量    示例：1
        //             'price'                => $vv['price'],//价格，精确到2位小数，单位元。如200.07，表示200元7分
        //             'total_fee'            => $vv['total_fee'],//退款申请金额，精确到2位小数
        //             'citemID'              => $vv['citemID'],//商品skuID    示例：1162770732994816
        //             'actualReturnQuantity' => $vv['actualReturnQuantity'],//实际收货数量    示例：1
        //             'isGift'               => $vv['isGift'],//是否赠品    示例：0
        //             'created'              => $vv['created'],//退款申请时间
        //             'productID'            => $vv['productID'],//商品ID    示例：1162770706141440
        //             'cTradeCodeLine'       => $vv['cTradeCodeLine'],//电商订单号    示例：DSDD11062019041000000001
        //             'cTradeLineId'         => $vv['cTradeLineId'],//电商订单行ID    示例：1174095207993601
        //             'num_iid'              => $vv['num_iid'] ?? $vv['product_code'],//平台商品编码    示例：526421307171
        //             'sku_id'               => $vv['sku_id'],//sku_id    示例：1162770732994816
        //         ];
        //     }
        //     $requestParam[] = [
        //         'plat'              => $v['plat'],//平台（含预留） 1—淘宝,2—京东,
        //         'shop_id'           => $v['shop_id'],//店铺ID
        //         'refund_id'         => 'AFRE' . date('YmdHis') . substr(microtime(), 2, 6),//退款单号
        //         'tid'               => $v['tid'],//交易编号
        //         'oribillid'         => $v['oribillid'],//退款单原单id
        //         'refund_type'       => $v['refund_type'],//退款类型 1-退款
        //         'refund_phase'      => $v['refund_phase'],//退款阶段 aftersale-售后
        //         'order_status'      => $v['order_status'],//交易状态
        //         'good_status'       => $goodStatus,//货物状态
        //         'refundNum'         => $v['refundNum'],//退货数量
        //         'total_fee'         => $v['total_fee'],//	可退金额，精确到2位小数
        //         'created'           => $v['created'],//退款申请时间
        //         'reason'            => $params['order']['exceptReason'] ?? '下游申请订单退款作废',
        //         'buyer_nick'        => $v['buyer_nick'],//买家昵称
        //         'srctype'           => $v['srctype'],//单据来源 2-导入
        //         'refundOrderDetail' => $refundOrderDetail
        //     ];
        // }
        // $data = [
        //     'method' => 'cancelOrder',
        //     'data'   => [
        //         'externalData' => $requestParam
        //     ],
        // ];
        // return $this->execute($data);
    }

    /**
     * 查询订单不是原单
     */
    public function queryTradeOrder($order_sn, $shopcode, $status = '') {
        $reqData = [
            'shopcode'         => $shopcode,//店铺编码
            'tid'              => $order_sn,//交易编号
            'pageIndex'        => 1,
            'pageSize'         => 10,
            // 'status'           => 'sellers_have_been_shipped',//已完成
            'headselectfields' => 'id,cShopID,tid,total_fee,payment,post_fee,cExpressCoID,cExpressCode,pubts',//需要返回的订单头字段
            'bodyselectfields' => 'id,citemID,num_iid,price,num,sku_id,invoice_no,status,logistics_company,cWhCode',//需要返回的订单体字段
            // 'id' => ??? 订单id,
        ];
        if (!empty($status)) {
            $reqData['sysstatus'] = $status;
        }
        $requestParam = [
            'method' => 'queryTradeOrder',
            'data'   => [
                "partParam" => $reqData,
            ],
        ];
        return $this->execute($requestParam);
    }

    /**
     * 获取发货物流信息
     * 请求域名 https://yonbip-core3.diwork.com/iuap-api-gateway
     * 请求地址 /yonbip/sd/dst/tradevouch/query
     */
    public function queryOrderExpress($param, $binfo) {
        if (!isset($binfo['event_code']) || empty($binfo['event_code'])) {
            return Normal::returnCode(Normal::FAIL, "渠道商未配置用友店铺编码，请联系相关人员");
        }
        return $this->queryTradeOrder($param['supplier_dsn'], $binfo['event_code'], 'shipconfirm');

        // $order_sn     = $param['supplier_dsn'];
        // $data         = [
        //     "partParam" => [
        //         'shopcode'         => $binfo['event_code'],//店铺编码
        //         'tid'              => $order_sn,//交易编号
        //         'pageIndex'        => 1,
        //         'pageSize'         => 10,
        //         'status'           => 'sellers_have_been_shipped',//已完成
        //         'headselectfields' => 'plat,shop_id,shopCode,tid,status,payment,warehouse_id,express_id,store_id',//需要返回的订单头字段
        //         'bodyselectfields' => 'tid,oid,status,sku_id,logistics_company,invoice_no,citemID,productID,productCode,skuCode',//需要返回的订单体字段
        //         // 'id' => ??? 订单id,
        //     ],
        // ];
        // $requestParam = [
        //     'method' => 'queryExpress',
        //     'data'   => $data,
        // ];
        // return $this->execute($requestParam);
    }

    /**
     * 参照订单生退换货单
     * "ids": "订单查询接口得到的info里面的id",
     * "partParam": {
     *      "订单查询接口得到的info里面的id": "订单查询接口得到的info里面的pubts"
     * },
     * "externalData": {
     *      "bodyIds": "订单查询接口得到的info里面的tradeorderdetail里面的id"
     * }
     */
    public function generateRefundOrder($data) {
        $requestParam = [
            'method' => 'generateRefundOrder',
            'data'   => [
                'ids'          => $data['ids'],//'订单查询接口得到的info里面的id',
                'partParam'    => [
                    // "订单查询接口得到的info里面的id" => "订单查询接口得到的info里面的pubts"
                    $data['ids'] => $data['pubts']
                ],
                'externalData' => [
                    "bodyIds" => implode(',', $data['bodyIds']),//"订单查询接口得到的info里面的tradeorderdetail里面的id"
                ],
            ],
        ];
        return $this->execute($requestParam);
    }

    /**
     * 商品列表 只维护价格和库存
     * 请求域名    https://yonbip-core3.diwork.com/iuap-api-gateway
     * 请求地址    /yonbip/digitalModel/product/list
     */
    public function queryGoodsList($param = []) {
        $codeArr           = $param['codeArr'];
        $stockBatchListArr = $this->coGetStockNum($codeArr);
        $stockBatchList    = $stockBatchListArr['stockBatchList'];
        $priceList         = [];
        if ($stockBatchListArr['queryPriceArr']) {
            $priceList = $this->coGetGoodsPrice($stockBatchListArr['queryPriceArr']);
        }
        $newData = [];
        foreach ($codeArr as $code) {
            $priceInfo = $priceList[$code] ?? [];
            $stockInfo = $stockBatchList[$code] ?? [];
            $newData[] = [
                'stockInfo' => $stockInfo,
                'priceInfo' => $priceInfo,
                'code'      => $code,
            ];
        }
        // echo json_encode($newData,320);
        $result = ['total' => count($newData), 'data' => $newData];
        return Normal::returnCode(Normal::SUC, '获取成功', $result);

        // $requestParam = [
        //     'method' => 'queryGoods',
        //     'data'   => [
        //         'pageIndex' => $param['page'] ?? 1,
        //         'pageSize'  => $param['limit'] ?? 100,
        //     ]
        // ];
        // $response     = $this->execute($requestParam);
        // if ($response['code'] != Normal::SUC) {
        //     return $response;
        // }
        // if (!isset($response['data']['data']['recordList']) || empty($response['data']['data']['recordList'])) {
        //     return Normal::returnCode(Normal::FAIL, '物料档案列表为空');
        // }
        $newData = [];
        // for ($i = 1; $i <= $response['data']['data']['pageCount']; $i++) {
        $requestParam = [
            'method' => 'queryGoods',
            'data'   => [
                // 'pageIndex' => $i,
                'pageIndex' => $param['page'] ?? 1,
                'pageSize'  => $param['limit'] ?? 100,
            ]
        ];
        $response     = $this->execute($requestParam);
        if ($response['code'] != Normal::SUC) {
            return $response;
        }
        if (!isset($response['data']['data']['recordList']) || empty($response['data']['data']['recordList'])) {
            // return Normal::returnCode(Normal::FAIL, "物料档案列表为空[pageIndex:{$i}]");
            // return Normal::returnCode(Normal::FAIL, "物料档案列表为空[pageIndex:{$param['page']}]");
            return Normal::returnCode(Normal::SUC, '获取完成', ['total' => 0, 'data' => []]);
        }
        $maxPageNum = $response['data']['data']['pageCount'];
        //物料id
        $goodsIds = [];
        foreach ($response['data']['data']['recordList'] as $item) {
            $goodsIds[$item['id']] = [
                'goods_id' => $item['id'],
                'org_id'   => $item['orgId'],
            ];
        }
        if (!$goodsIds) {
            // return Normal::returnCode(Normal::FAIL, "物料档案列表获取物料id为空[pageIndex:{$i}]");
            return Normal::returnCode(Normal::FAIL, "物料档案列表获取物料id为空[pageIndex:{$param['page']}]");
        }
        $priceInfo = [];
        //暂时不需要
        // $priceInfo = $this->coGetGoodsPrice($goodsIds);

        $codeArr = array_column($response['data']['data']['recordList'], 'code');

        $stockBatchList = $this->coGetStockNum($codeArr);

        //组装数据
        foreach ($response['data']['data']['recordList'] as $v) {
            // if (isset($stockBatchList[$v['code']]) && !empty($stockBatchList[$v['code']])) {
            $newData[] = [
                'id'           => $v['id'],
                'unit'         => $v['unit_Name'] ?? '',//主计量单位名称
                'brand'        => $v['brand_Name'] ?? '',//品牌名称
                'code'         => $v['code'],//物料编码
                'class'        => $v['manageClass_Name'] ?? '',//商品分类名称
                'name'         => $v['name']['zh_CN'] ?? '',//物料名称
                'weight'       => $v['weight'] ?? '0',//重量
                'url'          => $v['url'] ?? '',//物料首图片
                'fMarketPrice' => $v['detail']['fMarketPrice'] ?? '0.00',//市场价
                'barCode'      => $v['detail']['barCode'] ?? '',//条形码
                'priceInfo'    => $priceInfo[$v['id']] ?? [],
                'stockInfo'    => $stockBatchList[$v['code']] ?? [],
                //还差价格---------------------
            ];
            // }
        }
        // }
        if ($param['page'] == $maxPageNum) {
            $result = ['total' => count($newData), 'data' => $newData, 'hasPage' => 0];
        } else {
            $result = ['total' => count($newData), 'data' => $newData];
        }
        return Normal::returnCode(Normal::SUC, '获取成功', $result);
    }

    /**
     * 协程获取价格
     */
    public function coGetGoodsPrice($stockBatchList) {
        $priceInfo = [];
        $count     = count($stockBatchList);
        $wg        = new WaitGroup();
        $wg->add($count);
        foreach ($stockBatchList as $stock) {
            co(function () use ($wg, $stock, &$priceInfo) {
                //结算价格
                $priceResult = $this->queryGoodsPrice($stock);
                if ($priceResult['code'] == Normal::SUC) {
                    if (isset($priceResult['data']['data']['dataList']) && !empty($priceResult['data']['data']['dataList'])) {
                        $dataList1 = reset($priceResult['data']['data']['dataList']);
                        if (isset($dataList1['dataList']) && !empty($dataList1['dataList'])) {
                            $dataList2                   = reset($dataList1['dataList']);
                            $priceInfo[$stock['code']][] = [
                                'price'       => $dataList2['price'] ?? '0.00',//单价
                                'originBatch' => $stock['originBatch'],//批次
                            ];
                        }
                    }
                }
                $wg->done();
            });
        }
        $wg->wait();
        return $priceInfo;


        $priceInfo = [];
        $count     = count($goodsIds);
        $wg        = new WaitGroup();
        $wg->add($count);
        foreach ($goodsIds as $goods_id => $idItem) {
            co(function () use ($wg, $idItem, $goods_id, &$priceInfo) {
                //价格
                $priceResult = $this->queryGoodsPrice($idItem);
                if ($priceResult['code'] == Normal::SUC) {
                    if (isset($priceResult['data']['data']['detail']) && !empty($priceResult['data']['data']['detail'])) {
                        $priceDetail          = $priceResult['data']['data']['detail'];
                        $priceInfo[$goods_id] = [
                            'batchPrice'       => $priceDetail['batchPrice'] ?? '0.00',//批发价
                            'fMarkPrice'       => $priceDetail['fMarkPrice'] ?? '0.00',//建议零售价
                            'fLowestMarkPrice' => $priceDetail['fLowestMarkPrice'] ?? '0.00',//最低零售价
                            'fSalePrice'       => $priceDetail['fSalePrice'] ?? '0.00',//线上零售价
                            'fMarketPrice'     => $priceDetail['fMarketPrice'] ?? '0.00',//市场价,
                            'productspecitems' => $priceResult['data']['data']['productspecitems'] ?? [],//规格明细
                            'description'      => $priceResult['data']['data']['description']['description'] ?? '',//描述
                        ];
                    }
                }
                $wg->done();
            });
        }
        $wg->wait();
        return $priceInfo;
    }

    /**
     * 协程获取库存和批次
     */
    public function coGetStockNum($codeArr) {
        $stockBatchList = [];
        $queryPriceArr  = [];
        // $warehouseIds   = [];
        // foreach ($this->warehouse as $warehouse_id => $warehouse_code) {
        //     array_push($warehouseIds, (string)$warehouse_id);
        // }
        $stockList = $this->queryStockNum($codeArr);
        if ($stockList['code'] == Normal::SUC) {
            if (isset($stockList['data']['data']['recordList']) && !empty($stockList['data']['data']['recordList'])) {
                foreach ($stockList['data']['data']['recordList'] as $kk => $vv) {
                    //只要这几个仓库的批次
                    // if (in_array($vv['warehouse'], $warehouseIds)) {
                    if ($vv['warehouse'] == $this->config['warehouse']) {
                        $invaliddate = $vv['invaliddate'] ?? '';
                        $unixTime    = strtotime($invaliddate);
                        $baseBatch   = '基准批次' . $kk;
                        if (!$unixTime) {
                            $batchno = $vv['batchno'] ?? $baseBatch;
                        } else {
                            $batchno = date('Y-m-d', $unixTime);
                        }
                        $originBatch = $vv['batchno'] ?? $batchno;
                        $stockBatchList[$vv['product_cCode']][] = [
                            'num'         => $vv['availableqty'] ?? 0,
                            'batchno'     => $batchno,
                            // 'batchno'     => $batchno == $originBatch ? $batchno : $batchno . '/' . $originBatch,
                            'product'     => $vv['product'],//物料id
                            'warehouse'   => $vv['warehouse'],//仓库id
                            'originBatch' => $vv['batchno'] ?? $batchno,
                            // 'originBatch' => $originBatch,
                        ];
                        $queryPriceArr[]                        = [
                            'code'        => $vv['product_cCode'],//物料编码
                            'product'     => $vv['product'],//物料id
                            'warehouse'   => $vv['warehouse'],//仓库id
                            'originBatch' => $vv['batchno'] ?? $batchno,
                            // 'originBatch' => $originBatch,
                        ];
                    }
                }
            }
        }
        return ['stockBatchList' => $stockBatchList, 'queryPriceArr' => $queryPriceArr];

        // $count          = count($codeArr);
        // $wg             = new WaitGroup();
        // $wg->add($count);
        // foreach ($codeArr as $code) {
        //     co(function () use ($wg, $code, &$stockBatchList) {
        //         //库存
        //         $stockList = $this->queryStockNum($code);
        //         if ($stockList['code'] == Normal::SUC) {
        //             if (isset($stockList['data']['data']['recordList']) && !empty($stockList['data']['data']['recordList'])) {
        //                 foreach ($stockList['data']['data']['recordList'] as $vv) {
        //                     //只要这几个仓库的批次
        //                     if (in_array($vv['warehouse'], $warehouseIds)) {
        //                         $stockBatchList[$vv['product_cCode']][] = [
        //                             'num'     => $vv['availableqty'] ?? 0,
        //                             'batchno' => $vv['batchno'] ?? '基准批次'
        //                         ];
        //                     }
        //                 }
        //             }
        //         }
        //         $wg->done();
        //     });
        // }
        // $wg->wait();
        // return $stockBatchList;
    }


    /**
     * 商品详情
     * 请求域名    https://yonbip-core3.diwork.com/iuap-api-gateway
     * 请求地址    /yonbip/digitalModel/product/detail
     */
    public function queryGoodsPrice($item) {
        $requestParam = [
            'method' => 'queryBalance',
            'data'   => [
                'dataType'    => 1,//数据类型：1.期初成本 2.期末成本 3.年初成本 4.最新成本    示例：1
                'accentity'   => $this->config['accentity'],
                'resultCount' => 10,
                'date'        => date('Y-m-d'),
                'params'      => [
                    [
                        'accBook'    => $this->config['accbook'],
                        'accpurpose' => $this->config['accpurpose'],
                        'stockOrg'   => $this->config['stockOrg'],
                        'warehouse'  => $item['warehouse'],
                        'materialId' => $item['product'],
                        // 'batchCode'  => $item['originBatch'],
                    ]
                ],
            ]
        ];
        $result       = $this->execute($requestParam);
        if ($result['code'] != Normal::SUC) {
            return Normal::returnCode(Normal::FAIL, "物料档案详情获取价格失败物料code：{$item['product']}");
        }
        return $result;
    }

    /**
     * 查询可用库存
     * 请求域名 https://yonbip-core3.diwork.com/iuap-api-gateway
     * 请求地址 /yonbip/scm/stockanalysis/list
     */
    public function queryStockNum($code = [], $batchno = '') {
        $reqData = [
            'pageSize'      => 100,
            'pageIndex'     => 1,
            // 'product.cName' => [],//商品主键
            // 'productsku.skuName' => [],//sku主键
            // 'product_cName' => [],//物料名称
            'product_cCode' => $code,//物料编码
        ];
        if ($batchno) {
            $reqData['batchno'] = $batchno;
        }
        $requestParam = [
            'method' => 'queryStockNum',
            'data'   => $reqData,
        ];
        $result =  $this->execute($requestParam);
        if ($result['code'] != Normal::SUC) {
            return $result;
        }
        if (!isset($result['data']['data']['recordList']) || empty($result['data']['data']['recordList'])) {
            return Normal::returnCode(Normal::FAIL, '库存查询表为空', []);
        }
        //一次性查出所有的
        $maxCount = $result['data']['data']['recordCount'];
        $reqData = [
            'pageSize'      => $maxCount,
            'pageIndex'     => 1,
            // 'product.cName' => [],//商品主键
            // 'productsku.skuName' => [],//sku主键
            // 'product_cName' => [],//物料名称
            'product_cCode' => $code,//物料编码
        ];
        if ($batchno) {
            $reqData['batchno'] = $batchno;
        }
        $requestParam = [
            'method' => 'queryStockNum',
            'data'   => $reqData,
        ];
        return $this->execute($requestParam);
    }

    /**
     * 查询仓库详情
     */
    public function queryWarehouse($warehouse_id, $fields = '') {
        $requestParam = [
            'method'        => 'queryWarehouse',
            'data'          => [
                'id' => $warehouse_id,
            ],
            'requestMethod' => 'get'
        ];
        $result       = $this->execute($requestParam);
        if ($result['code'] != Normal::SUC) {
            return Normal::returnCode(Normal::FAIL, "获取仓库详情查询失败id：{$warehouse_id}");
        }
        if (!isset($result['data']['data']) || empty($result['data']['data'])) {
            return Normal::returnCode(Normal::FAIL, "获取仓库详情查询为空id：{$warehouse_id}");
        }
        return $result['data']['data'][$fields] ?? $result;
    }

    /**
     * 获取access_token
     * @return array
     * @author: hj
     */
    protected function getAccessToken() {

        // $redis = waiter(function () {
        //     return redis();
        // });
        // $token = $redis->get(self::SHOP_YONGYOU_ACCESS_TOKEN_PREFIX);
        // if (!empty($token)) {
        //     return Normal::returnCode(Normal::SUC, "缓存获取access_token成功", $token);
        // }
        $tmp       = time();
        $strA      = 'appKey' . $this->config['appKey'] . 'timestamp' . $tmp;
        $signA     = hash_hmac('sha256', $strA, $this->config['appSecret'], true);
        $sign      = base64_encode($signA);
        $arr       = [
            'appKey'    => $this->config['appKey'],
            'timestamp' => $tmp,
            'signature' => $sign,
        ];
        $url       = $this->config['accessTokenUrl'] . "?" . http_build_query($arr);
        $parameter = [
            [
                'tag'    => self::SUPPLIER_CODE . '_getAccessToken',
                'uid'    => IdService::instance()->getOtherID(),
                'url'    => $url,
                'data'   => [],
                'method' => 'get',
                'format' => 'json',
                'header' => [
                    "Content-Type: application/json",
                ],
            ],
        ];
        $resTask   = TaskWorker::instance()->addTask($parameter, 'handleDiableTask');
        $resTask   = current($resTask);
        $result    = @json_decode($resTask['response']['result'], true);
        if (isset($result['code']) && $result['code'] === '00000') {
            if (!isset($result['data']['access_token']) && empty($result['data']['access_token'])) {
                return Normal::returnCode(Normal::FAIL, '获取access_token为空');
            }
            $token = $result['data']['access_token'];
            //2个小时有效期 存入redis 1小时
            // $redis->set(self::SHOP_YONGYOU_ACCESS_TOKEN_PREFIX, $token, self::ACCESS_TOKEN_EXPIRE);

            return Normal::returnCode(Normal::SUC, "获取access_token成功", $token);
        }
        return Normal::returnCode(Normal::FAIL, $result['message'] ?? '获取access_token失败');
    }

    /**
     * CURL请求
     * @param $params
     * @return array
     */
    public function execute($param = []) {
        if (!isset(self::$apiMap[$param['method']])) {
            return Normal::returnCode(Normal::FAIL, "请求路由未设置");
        }
        if (empty($param['data'])) {
            return Normal::returnCode(Normal::FAIL, "数据不能为空");
        }
        if (empty($this->config['baseUrl'])) {
            return Normal::returnCode(Normal::FAIL, "接口地址不能为空");
        }
        $accessTokenRes = $this->getAccessToken();
        if ($accessTokenRes['code'] != Normal::SUC) {
            return Normal::returnCode(Normal::FAIL, $accessTokenRes['msg'] ?? '获取access_token失败');
        }
        $accessToken = $accessTokenRes['data'];
        $url         = $this->config['baseUrl'] . self::$apiMap[$param['method']] . '?access_token=' . $accessToken;
        if (isset($param['requestMethod'])) {
            $url = $url . '&' . http_build_query($param['data']);
        }
        $data      = $param['data'];
        $parameter = [
            [
                'tag'    => self::SUPPLIER_CODE . '_' . $param['method'],
                'uid'    => IdService::instance()->getOtherID(),
                'url'    => $url,
                'data'   => isset($param['requestMethod']) ? [] : $data,
                'method' => $param['requestMethod'] ?? 'post',
                'format' => 'json',
                'header' => [
                    "Content-Type: application/json",
                ],
            ],
        ];
        if (in_array($param['method'], ['queryGoods', 'queryBalance', 'queryStockNum', 'queryWarehouse'])) {
            $resTask = TaskWorker::instance()->addTask($parameter, 'handleDiableTask');
        } else {
            $resTask = TaskWorker::instance()->addTask($parameter);
        }
        $resTask = current($resTask);
        $result  = @json_decode($resTask['response']['result'], true);
        if (isset($result['code']) && $result['code'] == Normal::SUC) {
            return Normal::returnCode(Normal::SUC, "请求成功", $result);
        }
        if ($result['code'] == 310036) {
            return Normal::returnCode(Normal::FAIL, "{$result['message']}请求失败token过期");
        }
        return Normal::returnCode(Normal::FAIL, $result['message'] ?? '请求失败');
    }
}